Skip to content

drivers: entropy: stm32: make get_entropy_isr re-entrant #91593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mathieuchopstm
Copy link
Collaborator

The current get_entropy_isr implementation is not re-entrant; in fact, it will always deadlock when a re-entrant call is performed, because the logic to determine whether a call should disable the RNG or not after completion is inverted (the RNG is "acquired" when its interrupt is DISABLED, not when it is ENABLED) ==> re-entrant calls will always disable the RNG before return. Depending on where the original/pre-empted call was when it was interrupted, this can lead to the function polling the (now disabled) RNG for entropy that will never arrive. Inverting the logic seems like a fix, but is actually incomplete as there are situations where this information is not sufficient alone to determine the proper action to take.

Implement proper logic to determine whether a call is re-entrant, using the status of the RNG peripheral clock, the RNG status register and the HSEM on series where it is relevant.

The current `get_entropy_isr` implementation is not re-entrant; in fact, it
will always deadlock when a re-entrant call is performed, because the logic
to determine whether a call should disable the RNG or not after completion
is inverted (the RNG is "acquired" when its interrupt is DISABLED, not when
it is ENABLED), so re-entrant calls will always disable the RNG before
return. Depending on where the original/pre-empted call was when it was
interrupted, this can lead to the function polling the (now disabled) RNG
for entropy that will never arrive. Inverting the logic seems like a fix,
but is actually incomplete as there are situations where this information
is not sufficient alone to determine the proper action to take.

Implement proper logic to determine whether a call is re-entrant, using the
status of the RNG peripheral clock, the RNG status register and the HSEM on
series where it is relevant.

Signed-off-by: Mathieu Choplain <mathieu.choplain@st.com>
Copy link

@mathieuchopstm mathieuchopstm added this to the v4.2.0 milestone Jun 18, 2025
@str4t0m str4t0m self-requested a review June 25, 2025 12:33
@mathieuchopstm mathieuchopstm modified the milestones: v4.2.0, v4.3.0 Jun 27, 2025
Copy link
Collaborator

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation seems quite complex. I fear this may hide issues.

* but implemented in v1.1.0 - this wrapper can be removed
* when the STM32CubeWB0 is updated in hal_stm32.
*/
return (READ_BIT(RNGx->CR, RNG_CR_DISABLE) == LL_RNG_CR_DISABLE_0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking: mimic expect LL implementation and prevent bool/uint32_t implicit cast?

    return READ_BIT(RNGx->CR, RNG_CR_DISABLE) != (RNG_CR_DISABLE)) ? 1UL : 0UL;

{
#if defined(CONFIG_SOC_STM32WB09XX)
/**
* LL_RNG_IsEnabled() is missing from STM32CubeWB0 v1.0.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpciking also:

Suggested change
* LL_RNG_IsEnabled() is missing from STM32CubeWB0 v1.0.0
* LL_RNG_IsEnabled() is missing from STM32CubeWB0 v1.0.0 for WB09

/**
* z_stm32_hsem_is_owned() evaluates to false on single-CPU SoCs,
* but we always own RNG on these SoCs since there's only one CPU.
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entropy_stm32.c is the sole caller of z_stm32_hsem_is_owned(). For consistency I think this SoC helper function should return true if there is no other possible owner, that is when not WBX, MPx or H7 dual core.

*/
if (z_stm32_hsem_is_owned(CFG_HW_RNG_SEMID)) {
rng_already_acquired = true;
}
acquire_rng();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok to acquire the RNG (possibly polling on a HSEM) with interrupts locked?

@mathieuchopstm mathieuchopstm marked this pull request as draft June 27, 2025 09:37
@mathieuchopstm
Copy link
Collaborator Author

Converting to draft and moving to 4.3.0 as this will require rework

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants